﻿import L from "leaflet";
import { initShaders } from "./gllib";
import vertexSHADER from "./shader_Vertex.glsl?raw";
import fragmentSHADER from "./shader_Fragment.glsl?raw";

L.Scalarlayer = L.Layer.extend({
  _map: null,
  _container: null,
  _canvas: null,
  _canvas_label: null,
  _webglcontext: null,
  _labelcontext: null,
  _gTexUnit: false,
  _gTexUnit1: false,
  _gTexUnit2: false,
  minValue: 0,
  maxValue: 0,
  colorTotalNum: 200,
  colorBarData: null,
  grid_data: null,
  texture_data: null,

  options: {
    zIndex: 0, //图层层级
    showLabel: false, //是否显示标注
    showColor: true, //是否显示颜色
    opacity: 1, //图层透明度
    scalarColor: null, //色带配置
    labelCell: 64, //label显示密度
    magnification: 1, //放大倍率
    nodata: -999,
    digit: 2,
    numRange: [-900, 99999999],
    range: {
      scale_lon: 0,
      scale_lat: 0,
      startLat: 0,
      startLon: 0,
      endLon: 0,
      endLat: 0,
      width: 0,
      height: 0,
    },
  },

  setData: function (data) {
    let self = this;
    self.grid_data = data;
    self.texture_data = new Uint8Array(data.length * data[0].length * 4);
    let ii = 0;
    for (let index = 0; index < data.length; index++) {
      for (let index2 = 0; index2 < data[index].length; index2++) {
        let num = data[index][index2];
        let integerPart = Math.floor(num);
        let decimalPartRaw = (num - integerPart).toFixed(2);
        let decimalPartMultiplied = Math.round(
          parseFloat(decimalPartRaw) * 100
        );

        self.texture_data[ii] = integerPart;
        self.texture_data[ii + 1] = decimalPartMultiplied;
        self.texture_data[ii + 2] = 255;
        self.texture_data[ii + 3] = 255;

        if (integerPart == -999) {
          self.texture_data[ii] = 0;
          self.texture_data[ii + 1] = 0;
          self.texture_data[ii + 2] = 255;
          self.texture_data[ii + 3] = 255;
          // self.texture_data[ii + 3] = 0;
        }
        ii += 4;
      }
    }
    self._reset();
  },
  _reset: function () {
    let self = this;
    if (!self._map) {
      return;
    }
    let size = self._map.getSize(),
      lt = self._map.containerPointToLayerPoint([0, 0]);
    L.DomUtil.setPosition(self._container, lt);

    self._container.style.width = size.x + "px";
    self._container.style.height = size.y + "px";

    self._canvas.width = size.x * self.options.magnification;
    self._canvas.height = size.y * self.options.magnification;
    self._canvas.style.width = size.x + "px";
    self._canvas.style.height = size.y + "px";
    self._canvas.style.position = "absolute";
    self._canvas.style.left = "0";
    self._canvas.style.top = "0";

    self._canvas_label.width = size.x;
    self._canvas_label.height = size.y;
    self._canvas_label.style.width = size.x + "px";
    self._canvas_label.style.height = size.y + "px";
    self._canvas_label.style.position = "absolute";
    self._canvas_label.style.left = "0";
    self._canvas_label.style.top = "0";

    self._draw();
  },
  _draw: function () {
    let self = this;
    if (L.Browser.canvas && self._map) {
      let self = this;
      self._webglcontext = self._canvas.getContext("experimental-webgl", {
        preserveDrawingBuffer: true,
      });
      self._drawbytexture();

      self._labelcontext = self._canvas_label.getContext("2d", {
        willReadFrequently: true,
      });
      let Cwidth = self._canvas.clientWidth;
      let Cheight = self._canvas.clientHeight;
      let header = self.options.range;
      self._drawlabel(
        self._labelcontext,
        Cwidth,
        Cheight,
        header.startLon,
        header.startLat,
        header.scale_lon,
        header.scale_lat,
        self.grid_data
      );
    }
  },
  _drawbytexture: function () {
    let self = this;
    let gl = self._webglcontext;
    gl.viewport(0, 0, self._canvas.width, self._canvas.height);
    gl.clearColor(0.0, 0.0, 0.0, 0.0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.clear(gl.DEPTH_BUFFER_BIT);
    if (!self.options.showColor) {
      return;
    }
    if (!gl) {
      console.log("无法获取WebGL的呈现上下文!");
      return;
    }
    if (!initShaders(gl, vertexSHADER, fragmentSHADER)) {
      //配置着色器
      console.log("无法初始化着色器!");
      return;
    }
    let n = self._initVertexBuffers(gl); //配置顶点信息
    if (n < 0) {
      console.log("无法获取点信息!");
      return;
    }
    if (!self._initTextures(gl, n)) {
      //配置纹理
      console.log("无法配置纹理!");
      return;
    }
  },
  _initVertexBuffers: function (gl) {
    let self = this;
    let n = 4;
    let texturey = 1.0;
    let verticesSizes = new Float32Array([
      //四个顶点的位置和纹理数据范围
      -1,
      1,
      0.0,
      texturey,
      -1,
      -1,
      0.0,
      0.0,
      1,
      1,
      1.0,
      texturey,
      1,
      -1,
      1.0,
      0.0,
    ]);

    let vertexSizeBuffer = gl.createBuffer();
    if (!vertexSizeBuffer) {
      console.log("无法创建缓冲区");
      return -1;
    }
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexSizeBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, verticesSizes, gl.STATIC_DRAW);

    let a_Position = gl.getAttribLocation(gl.program, "a_Position");
    if (a_Position < 0) {
      console.log("无法获取到存储位置");
      return;
    }
    let fsize = verticesSizes.BYTES_PER_ELEMENT;
    gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, fsize * 4, 0);
    gl.enableVertexAttribArray(a_Position);

    let dataRange = gl.getUniformLocation(gl.program, "dataRange");
    if (!dataRange) {
      console.log("未能获取dataRange的存储位置!");
      return;
    }
    gl.uniform4f(
      dataRange,
      self.options.range.startLat,
      self.options.range.endLat,
      self.options.range.startLon,
      self.options.range.endLon
    );

    let u_Scale_lon = gl.getUniformLocation(gl.program, "u_Scale_lon");
    if (!u_Scale_lon) {
      console.log("未能获取u_Scale_lon的存储位置!");
      return;
    }
    gl.uniform1f(u_Scale_lon, self.options.range.scale_lon);

    let u_Scale_lat = gl.getUniformLocation(gl.program, "u_Scale_lat");
    if (!u_Scale_lat) {
      console.log("未能获取u_Scale_lat的存储位置!");
      return;
    }
    gl.uniform1f(u_Scale_lat, self.options.range.scale_lat);

    let u_Startlon = gl.getUniformLocation(gl.program, "u_Startlon");
    if (!u_Startlon) {
      console.log("未能获取u_Startlon的存储位置!");
      return;
    }
    gl.uniform1f(u_Startlon, self.options.range.startLon);

    let u_Startlat = gl.getUniformLocation(gl.program, "u_Startlat");
    if (!u_Startlat) {
      console.log("未能获取u_Startlat的存储位置!");
      return;
    }
    gl.uniform1f(u_Startlat, self.options.range.startLat);

    let pic_width = gl.getUniformLocation(gl.program, "pic_width");
    if (!pic_width) {
      console.log("未能获取pic_width的存储位置!");
      return;
    }
    gl.uniform1f(pic_width, self.options.range.width);

    let pic_height = gl.getUniformLocation(gl.program, "pic_height");
    if (!pic_height) {
      console.log("未能获取pic_height的存储位置!");
      return;
    }
    gl.uniform1f(pic_height, self.options.range.height);

    let Llon = self._map.containerPointToLatLng(L.point(0, 0)).lng;
    let Rlon = self._map.containerPointToLatLng(
      L.point(self._canvas.clientWidth, 0)
    ).lng;
    let leftlon = gl.getUniformLocation(gl.program, "leftlon");
    if (!leftlon) {
      console.log("未能获取leftlon的存储位置!");
      return;
    }
    gl.uniform1f(leftlon, Llon);
    let lonspan = gl.getUniformLocation(gl.program, "lonspan");
    if (!lonspan) {
      console.log("未能获取lonspan的存储位置!");
      return;
    }
    gl.uniform1f(lonspan, Rlon - Llon);

    let widhei = gl.getUniformLocation(gl.program, "widhei");
    if (!widhei) {
      console.log("未能获取widhei的存储位置!");
      return;
    }
    gl.uniform2f(widhei, self._canvas.width, self._canvas.height);

    let numRange = gl.getUniformLocation(gl.program, "numRange");
    if (!numRange) {
      console.log("未能获取numRange的存储位置!");
      return;
    }
    gl.uniform2f(numRange, self.options.numRange[0], self.options.numRange[1]);

    let alpa = gl.getUniformLocation(gl.program, "_Alpha");
    if (!alpa) {
      console.log("未能获取_Alpha的存储位置!");
      return;
    }
    gl.uniform1f(alpa, self.options.opacity);

    let minValue = gl.getUniformLocation(gl.program, "minValue");
    if (!minValue) {
      console.log("未能获取minValue的存储位置!");
      return;
    }
    gl.uniform1f(minValue, self.minValue);

    let maxValue = gl.getUniformLocation(gl.program, "maxValue");
    if (!maxValue) {
      console.log("未能获取maxValue的存储位置!");
      return;
    }
    gl.uniform1f(maxValue, self.maxValue);

    let isMobileF = gl.getUniformLocation(gl.program, "isMobileF");
    if (!isMobileF) {
      console.log("未能获取isMobileF的存储位置!");
      return;
    }
    let valf = 0.0;
    gl.uniform1f(isMobileF, valf);
    return n;
  },
  _initTextures: function (gl, n) {
    let self = this;
    gl.getExtension("OES_texture_float");
    gl.getExtension("OES_texture_float_linear");
    let texture = gl.createTexture();
    let texture1 = gl.createTexture();
    let texture2 = gl.createTexture();
    if (!texture || !texture1 || !texture2) {
      console.log("无法创建纹理对象");
      return;
    }
    let u_Sampler = gl.getUniformLocation(gl.program, "u_Sampler");
    let u_Sampler1 = gl.getUniformLocation(gl.program, "u_Sampler1");
    let u_Sampler2 = gl.getUniformLocation(gl.program, "u_Sampler2");
    if (u_Sampler < 0 || u_Sampler1 < 0 || u_Sampler2 < 0) {
      console.log("无法获取变量的存储位置");
      return;
    }

    //------纬度纹理------
    let Cheight = self._canvas.clientHeight;
    let canvas_lat = document.createElement("canvas");
    canvas_lat.width = 1;
    canvas_lat.height = Cheight;
    if (Cheight == 0) {
      return;
    }
    let latctx = canvas_lat.getContext("2d", { willReadFrequently: true });
    let latlngTexture = latctx.getImageData(0, 0, 1, Cheight);
    for (let i = 0; i < Cheight; i++) {
      let lat = self._map.containerPointToLatLng(L.point(0, i)).lat;
      // if (lat < 0) { latlngTexture.data[i * 4 + 3] = 100 }
      if (lat < 0) {
        latlngTexture.data[i * 4 + 3] = 255;
      } else {
        latlngTexture.data[i * 4 + 3] = 0;
      }
      lat = Math.abs(lat);
      let latInt = parseInt(lat);
      latlngTexture.data[i * 4] = latInt;
      let xiaoshu =
        lat - latInt !== 0 ? (lat - latInt).toString().split(".")[1] : "0";
      if (xiaoshu.length < 12) {
        xiaoshu = xiaoshu?.PadRight(12, "0");
      }
      latlngTexture.data[i * 4 + 1] = parseInt(xiaoshu.substring(0, 2));
      latlngTexture.data[i * 4 + 2] = parseInt(xiaoshu.substring(2, 4));
      // latlngTexture.data[i * 4 + 3] = parseInt(xiaoshu.substring(4, 6))+latlngTexture.data[i * 4 + 3]
    }
    self._loadTexture(gl, n, texture, u_Sampler, self.texture_data, 0);
    self._loadTexture(gl, n, texture1, u_Sampler1, latlngTexture, 1);
    self._loadTexture(gl, n, texture2, u_Sampler2, self.colorBarData, 2);
    return true;
  },
  _loadTexture: function (gl, n, texture, u_Sampler, image, texUnit) {
    let self = this;
    //对纹理图像进行y轴反转
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
    //开启0号纹理单元
    if (texUnit == 0) {
      gl.activeTexture(gl.TEXTURE0);
      self._gTexUnit = true;
      //向target绑定纹理对象
      gl.bindTexture(gl.TEXTURE_2D, texture);
      //配置纹理参数
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
      //配置纹理图像
      // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image)
      // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image)
      // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, image.length / 4, 0, gl.RGBA, gl.FLOAT, image)
      gl.texImage2D(
        gl.TEXTURE_2D,
        0,
        gl.RGBA,
        self.options.range.width,
        self.options.range.height,
        0,
        gl.RGBA,
        gl.UNSIGNED_BYTE,
        image
      );
      //将纹理传递给着色器
      gl.uniform1i(u_Sampler, texUnit);
    } else if (texUnit == 1) {
      gl.activeTexture(gl.TEXTURE1);
      self._gTexUnit1 = true;
      //向target绑定纹理对象
      gl.bindTexture(gl.TEXTURE_2D, texture);
      //配置纹理参数
      gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
      gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
      gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
      //配置纹理图像
      gl.texImage2D(
        gl.TEXTURE_2D,
        0,
        gl.RGBA,
        gl.RGBA,
        gl.UNSIGNED_BYTE,
        image
      );
      //将纹理传递给着色器
      gl.uniform1i(u_Sampler, texUnit);
    } else if (texUnit == 2) {
      gl.activeTexture(gl.TEXTURE2);
      self._gTexUnit2 = true;
      //向target绑定纹理对象
      gl.bindTexture(gl.TEXTURE_2D, texture);
      //配置纹理参数
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); //NEAREST
      //配置纹理图像
      gl.texImage2D(
        gl.TEXTURE_2D,
        0,
        gl.RGBA,
        gl.RGBA,
        gl.UNSIGNED_BYTE,
        image
      );
      //将纹理传递给着色器
      gl.uniform1i(u_Sampler, texUnit);
    }
    //绘制
    if (self._gTexUnit && self._gTexUnit1 && self._gTexUnit2) {
      gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
      self._gTexUnit = false;
      self._gTexUnit1 = false;
      self._gTexUnit2 = false;
    }
  },
  _drawlabel: function (
    ctx,
    Cwidth,
    Cheight,
    startLon,
    startLat,
    datacell_lon,
    datacell_lat,
    data
  ) {
    let self = this,
      map = self._map;
    ctx.clearRect(0, 0, Cwidth, Cheight);
    if (!self.options.showLabel) {
      return;
    }
    let currentzoom = map.getZoom();
    let currentbounds = map.getBounds();
    let leftup = currentbounds.getNorthWest();
    let rightdown = currentbounds.getSouthEast();
    let range = self._getRange(leftup, rightdown, currentzoom);
    let zr = Math.pow(2, currentzoom);
    for (let i = range.up; i <= range.down; i++) {
      for (let j = range.left; j <= range.right; j++) {
        let zheng = Math.floor(j / zr);
        let yu = j % zr;
        if (yu < 0) {
          yu = yu + zr;
        }
        let row = i,
          col = yu;
        let cellInterval = (2 * Math.PI) / (256 * Math.pow(2, currentzoom));
        let firstX = col * cellInterval * 256 - Math.PI + cellInterval / 2;
        let firstY = Math.PI - row * cellInterval * 256 - cellInterval / 2;
        let interval = self.options.labelCell;
        for (let h = 0; h < 256 / interval; h++) {
          for (let w = 0; w < 256 / interval; w++) {
            try {
              let lonlat = self._getLonlat(
                firstX,
                firstY,
                cellInterval,
                w * interval,
                h * interval,
                interval / 2
              );
              let lon0 = lonlat.lon;
              let lat0 = lonlat.lat;
              let querylng = lon0;
              querylng = querylng % 360;
              if (querylng < 0) {
                querylng = querylng + 360;
              }
              let _row = Math.floor((startLat - lat0) / datacell_lat);
              let _col = Math.floor((querylng - startLon) / datacell_lon);
              if (
                _row < 0 ||
                _row > data.length ||
                _col < 0 ||
                _col >= data[0].length
              ) {
                continue;
              }
              if (data[_row][_col] == self.options.nodata) {
                continue;
              }
              if (
                data[_row][_col] <= self.options.numRange[0] ||
                data[_row][_col] >= self.options.numRange[1]
              ) {
                continue;
              }
              let txt = parseFloat(data[_row][_col]).toFixed(
                self.options.digit
              );
              ctx.font = "15px 微软雅黑";
              ctx.fillStyle = "rgba(0,0,0,0.5)";
              ctx.textAlign = "center";
              ctx.textBaseline = "middle";
              lon0 = lonlat.lon + 360 * zheng;
              let screenpoint = map.latLngToContainerPoint(
                L.latLng(lat0, lon0)
              );
              ctx.fillText(txt, screenpoint.x, screenpoint.y);
            } catch (error) {
              continue;
            }
          }
        }
      }
    }
  },

  /*------------------------------------ 外置函数 ------------------------------------------*/

  setZindex: function (zIndex) {
    this._container.style.zIndex = zIndex;
  },
  setShowColor: function (bool) {
    this.options.showColor = bool;
    if (this._map) {
      this._reset();
    }
  },
  setShowLabel: function (bool) {
    this.options.showLabel = bool;
    if (this._map) {
      this._reset();
    }
  },
  setOpacity: function (val) {
    this.options.opacity = val;
    if (this._map) {
      this._reset();
    }
  },
  setScalarColor: function (val) {
    this.options.scalarColor = val;
    this._initExtreme();
    if (this._map) {
      this._reset();
    }
  },

  /*------------------------------------ 事件 ------------------------------------------*/

  onAdd: function (map) {
    let self = this;
    self._map = map;
    if (!self._container) {
      self._initCanvas();
    }
    map._panes.overlayPane.appendChild(self._container);
    map.on("moveend", self._reset, this);
    // map.on('zoomstart', self._clearCanvas, this)
    // map.on('zoomend', self._draw, this)
    // map.on('move', self._reset, this)
    map.on("zoom", self._reset, this);
    if (map.options.zoomAnimation && L.Browser.any3d) {
      map.on("zoomanim", self._animateZoom, this);
    }
    self._initExtreme();
  },
  _initCanvas: function () {
    let self = this;
    self._container = L.DomUtil.create("div", "leaflet-image-layer");
    self._canvas = L.DomUtil.create("canvas", "");
    self._canvas_label = L.DomUtil.create("canvas", "");
    self.setZindex(self.options.zIndex);
    if (self._map.options.zoomAnimation && L.Browser.any3d) {
      L.DomUtil.addClass(self._canvas, "leaflet-zoom-animated");
      L.DomUtil.addClass(self._canvas_label, "leaflet-zoom-animated");
    } else {
      L.DomUtil.addClass(self._canvas, "leaflet-zoom-hide");
      L.DomUtil.addClass(self._canvas_label, "leaflet-zoom-animated");
    }
    self._container.appendChild(self._canvas);
    self._container.appendChild(self._canvas_label);
    L.extend(self._canvas, {
      onselectstart: L.Util.falseFn,
      onmousemove: L.Util.falseFn,
      onload: L.bind(self._onCanvasLoad, this),
    });
    L.extend(self._canvas_label, {
      onselectstart: L.Util.falseFn,
      onmousemove: L.Util.falseFn,
      onload: L.bind(self._onCanvasLoad, this),
    });
  },
  onRemove: function (map) {
    let self = this;
    try {
      if (self._webglcontext) {
        self._webglcontext.clearColor(0.0, 0.0, 0.0, 0.0);
        self._webglcontext.clear(self._webglcontext.COLOR_BUFFER_BIT);
        self._labelcontext.clearRect(0, 0, 5000, 5000);
      }
    } catch (e) {
      console.log(e);
    }
    map.getPanes().overlayPane.removeChild(this._container);
    map.off("moveend", self._reset, this);
    map.off("zoomstart", self._clearCanvas, this);
    // map.off('zoomend', self._draw, this)
    // map.off('move', self._reset, this)
    map.off("zoom", self._reset, this);
    if (map.options.zoomAnimation) {
      map.off("zoomanim", self._animateZoom, this);
    }
  },

  addTo: function (map) {
    map.addLayer(this);
    return this;
  },
  bringToBack: function () {
    let pane = this._map._panes.overlayPane;
    if (this._canvas) {
      pane.insertBefore(this._canvas, pane.firstChild);
    }
    return this;
  },
  initialize: function (options) {
    L.setOptions(this, options);
  },
  _animateZoom: function () {},
  _onCanvasLoad: function () {
    this.fire("load");
  },
  _setTransform: function (el, offset, scale) {
    let pos = offset || new L.Point(0, 0);
    el.style[L.DomUtil.TRANSFORM] =
      (L.Browser.ie3d
        ? "translate(" + pos.x + "px," + pos.y + "px)"
        : "translate3d(" + pos.x + "px," + pos.y + "px,0)") +
      (scale ? " scale(" + scale + ")" : "");
  },
  _clearCanvas: function () {
    let self = this;
    try {
      let ctx_label = self._canvas_label.getContext("2d", {
        willReadFrequently: true,
      });
      ctx_label.clearRect(
        0,
        0,
        self._canvas_label.clientWidth,
        self._canvas_label.clientHeight
      );
      let gl = self._canvas.getContext("experimental-webgl", {
        preserveDrawingBuffer: true,
      });
      gl.clearColor(0.0, 0.0, 0.0, 0.0);
      gl.clear(gl.COLOR_BUFFER_BIT);
      gl.clear(gl.DEPTH_BUFFER_BIT);
    } catch (e) {
      console.log(e);
    }
  },

  /*------------------------------------ 工具函数 ------------------------------------------*/

  /**创建图例dom */
  _creatLegend: function () {
    let canvas = document.createElement("div");
    canvas.id = "scalarLegend";
    canvas.style.position = "absolute";
    canvas.style.zIndex = "1000";
    canvas.style.top = "80px";
    canvas.style.left = "1rem";
    canvas.style.border = "1px solid #fff";
    canvas.style.boxShadow = "rgb(255 255 255) 0px 0px 2px 0px";
    canvas.style.display = "flex";
    canvas.style.flexDirection = "column";
    document.getElementById("map").appendChild(canvas);
  },
  /**初始化色带纹理及数据极值 */
  _initExtreme: function () {
    let self = this;
    let colorD = [];
    let colorz = self.options.scalarColor.sort(function (a, b) {
      //按value进行排序
      return a.value - b.value;
    });
    self.minValue = colorz[0].value;
    self.maxValue = colorz[colorz.length - 1].value;
    let unitColorNum = self.colorTotalNum / (self.maxValue - self.minValue);
    for (let iii = 0; iii < colorz.length - 1; iii++) {
      let t = Math.ceil(
        unitColorNum * (colorz[iii + 1].value - colorz[iii].value)
      );
      let a = self._interpolationColor(
        colorz[iii].color,
        colorz[iii + 1].color,
        t
      );
      colorD = colorD.concat(a);
    }
    let colorbar = document.createElement("canvas");
    colorbar.width = 1;
    colorbar.height = colorD.length;
    let colorbarctx = colorbar.getContext("2d", { willReadFrequently: true });
    let colorbard = colorbarctx.getImageData(0, 0, 1, colorbar.height);
    for (let i = 0; i < colorD.length; i++) {
      colorbard.data[i * 4] = colorD[i].r;
      colorbard.data[i * 4 + 1] = colorD[i].g;
      colorbard.data[i * 4 + 2] = colorD[i].b;
      colorbard.data[i * 4 + 3] = 255;
    }
    self.colorBarData = colorbard;
  },
  /**计算横轴墨卡托投影下的坐标 */
  _getCornerNum: function (lat, lon, level) {
    let d = Math.PI / 180;
    let x = lon * d;
    let y = Math.log(Math.tan(((90 + lat) * Math.PI) / 360)) / (Math.PI / 180);
    y = (y * Math.PI) / 180;
    //先转墨卡托，用墨卡托求行列号
    let rowNumber = ((Math.PI - y) / (2 * Math.PI)) * Math.pow(2, level);
    let colNumber = ((x + Math.PI) / (2 * Math.PI)) * Math.pow(2, level);
    return {
      rowNum: Math.round(rowNumber),
      colNum: Math.round(colNumber),
    };
  },
  /**根据经纬度计算行列号 */
  _getRange: function (leftup, rightdown, zoom) {
    let leftuprowcol = this._getCornerNum(leftup.lat, leftup.lng, zoom);
    let rightdownrowcol = this._getCornerNum(
      rightdown.lat,
      rightdown.lng,
      zoom
    );
    return {
      left:
        leftuprowcol.colNum === 0
          ? leftuprowcol.colNum
          : leftuprowcol.colNum - 1,
      up:
        leftuprowcol.rowNum === 0
          ? leftuprowcol.rowNum
          : leftuprowcol.rowNum - 1,
      right: rightdownrowcol.colNum,
      down: rightdownrowcol.rowNum,
    };
  },
  /**计算切片上点的坐标 */
  _getLonlat: function (x, y, cell, xAdd, yAdd, jian) {
    let lon = ((x + xAdd * cell + jian * cell) / Math.PI) * 180;
    let lat =
      (180 / Math.PI) *
      (2 *
        Math.atan(
          Math.exp(
            (((y - yAdd * cell - jian * cell) / Math.PI) * 180 * Math.PI) / 180
          )
        ) -
        Math.PI / 2);
    return { lon: lon, lat: lat };
  },
  /**插值颜色 */
  _interpolationColor: function (color1, color2, chazhigeshu) {
    let colorBarCanvas = document.createElement("canvas");
    colorBarCanvas.width = chazhigeshu;
    colorBarCanvas.height = 1;
    let ctx = colorBarCanvas.getContext("2d", { willReadFrequently: true });
    let grd = ctx.createLinearGradient(0, 1, chazhigeshu, 1);
    grd.addColorStop(0, color1);
    grd.addColorStop(1, color2);
    ctx.fillStyle = grd;
    ctx.fillRect(0, 0, chazhigeshu, 1);
    let colorZong = [];
    for (let iii = 0; iii < chazhigeshu; iii++) {
      let colorData = ctx.getImageData(iii, 0, 1, 1).data;
      colorZong.push({
        r: colorData[0],
        g: colorData[1],
        b: colorData[2],
      });
    }
    return colorZong;
  },
  /**转换风场UV值 */
  _computeWindUV: function (u_value, v_value) {
    let value = Math.sqrt(u_value * u_value + v_value * v_value);
    let angle = Math.acos(u_value / value);
    if (v_value < 0) {
      angle = -angle;
    }
    angle = Math.round((angle / Math.PI) * 180.0 + 90);
    if (angle < 0) {
      angle = angle + 360;
    }
    angle = Math.round(360 - angle);
    value = value.toFixed(2);
    return {
      value: parseFloat(value),
      angle: angle,
    };
  },
  /**转换流场UV值 */
  _UV2SDCur: function (u, v) {
    let spd, dir;
    if (u === 0 && v === 0) {
      spd = 0;
      dir = -9999;
      return { speed: spd, dir: dir };
    }
    if (u === 0 || v === 0) {
      if (u === 0) {
        spd = v < 0 ? -v : v;
        if (v > 0) {
          dir = Math.PI / 2;
        } else if (v < 0) {
          dir = (Math.PI * 3) / 2;
        }
      } else if (v === 0) {
        spd = u < 0 ? -u : u;
        if (u > 0) {
          dir = 0;
        } else if (u < 0) {
          dir = Math.PI;
        }
      }
      dir = (2.5 * Math.PI - dir) % (Math.PI * 2);
      return { speed: spd, dir: dir };
    }
    spd = Math.sqrt(u * u + v * v);
    dir = Math.atan(u / v);
    if (u < 0 && v > 0) {
      dir = (1 / 2.0) * Math.PI - dir;
    } else if (u < 0 && v < 0) {
      dir = (3 / 2.0) * Math.PI - dir;
    } else if (u > 0 && v < 0) {
      dir = (3 / 2.0) * Math.PI - dir;
    } else if (u > 0 && v > 0) {
      dir = (1 / 2.0) * Math.PI - dir;
    }
    dir = (2.5 * Math.PI - dir) % (Math.PI * 2);
    return { speed: spd, dir: dir };
  },
});

export default function (options) {
  return new L.Scalarlayer(options);
}
